﻿#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
using namespace std;

class Animal {
public:
	void speak() {
		cout << "Animal speak" << endl;
	}
	virtual void run() {
		cout << "Animal run" << endl; 
	}
};

// 编译器会根据函数调用的对象类型，在编译阶段就确定函数的调用地址，这就是静态联编（早绑定） 
void test01() {
	Animal an;
	an.speak();  // 静态联编，在编译阶段就确定好了函数的地址，不是在运行阶段，C语言都是这样的 
}

// 在运行阶段才确定调用哪个函数，这就是动态联编（晚绑定），需要使用虚函数 
// 虚函数：在普通成员函数前面加上virtual，该函数就变为虚函数，告诉编译器这个函数需要晚绑定，运行时确定函数地址 
class Dog : public Animal {
public:
	void speak() {
		cout << "Dog speak" << endl;
	}
	void run() {
		cout << "Dog run" << endl;
	}
};
/*
类型转换问题：
1. 子类转为父类（向上转换）：编译器认为指针的寻址范围缩小了，所以是安全的；
2. 父类转为子类（向下转化）：编译器认为指针的寻址范围扩大了，不安全。
*/
void doLogin(Animal *animal) {
	animal->speak();  // speak函数早绑定，传入的参数animal无论是Animal本身类型，还是Animal子类强转的，都会调用Animal::speak函数  
}
void test02() {
	Dog *d = new Dog;
	doLogin(d); // Animal speak 
}
void doLogin2(Animal *animal) {
	animal->run(); 
}
void test03() {
	Dog *d = new Dog;
	doLogin2(d); // Dog run  
}


int main()
{

	// test01(); 
	test02(); 
	test03(); 

	system("pause");
	return EXIT_SUCCESS;
}